package com.bytetool.agent.transformer;

import com.bytetool.agent.exception.ExceptionUtil;
import com.bytetool.agent.method.CtClassMethodUtil;
import com.bytetool.agent.method.PerformanceModifyMethod;
import javassist.CtClass;
import javassist.CtMethod;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

/**
 * @author zouhuixing
 * @date 2024/3/31
 */
public class PerformanceTransformer implements ClassFileTransformer {
    private String[] includes;

    private String[] excludes;

    public PerformanceTransformer(String[] includes, String[] excludes) {
        this.includes = includes;
        this.excludes = excludes;
    }

    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        if (CtClassMethodUtil.includes(excludes, className.replaceAll("/", "."))) {
            return new byte[0];
        }
        if (!CtClassMethodUtil.includes(includes, className.replaceAll("/", "."))) {
            return new byte[0];
        }
        try {
            CtClass ctClass = CtClassMethodUtil.getCtClass(loader, className);

            CtMethod[] methods = ctClass.getDeclaredMethods();
            for (CtMethod method : methods) {
                if (CtClassMethodUtil.shouldSkipCommonMethod(method.getName())) {
                    continue;
                }
                PerformanceModifyMethod.monitorMethodPerformance(ctClass, method);

            }
            return ctClass.toBytecode();
        } catch (Exception e) {
            ExceptionUtil.handleException(e);
        }
        return new byte[0];
    }
}
